struct Aho_Corasick_Automaton
{
    int ch[N][26],cnt[N],ne[N],cnt1,ans[N],Map[N],in[N],vis[N];
    void clear()
    {
        memset(ch,0,sizeof ch);
        memset(ne,0,sizeof ne);
        memset(ans,0,sizeof ans);
        memset(cnt,0,sizeof cnt);
        cnt1 = 0;
    }
    void ins(string s,int i)
    {
        int now = 0;
        for(int i = 0; i < s.size(); i ++)
        {
            int v = s[i] - 'a';
            if(!ch[now][v]) ch[now][v] = ++cnt1;//Trie树没有这个子节点,构造出来
            now = ch[now][v];//向下构造 
        }
        if(!cnt[now]) cnt[now] = i;//此单词没出现，记录 
        Map[i] = cnt[now];//Map[i]代表第i个模式串与的第T[root].end个模式串相同 
    } 
    //cnt[now] 代表节点now所记录的字符为一个模式串的末尾。

    void build()
    {
        queue<int>q;
        for(int i = 0; i < 26; i ++) 
            if(ch[0][i]) q.push(ch[0][i]);
            
        while(q.size())
        {
            int u = q.front();q.pop();
            for(int i = 0; i < 26; i ++)
            {
                int v = ch[u][i];
                if(v) 
                {
                    ne[v] = ch[ne[u]][i];
                    in[ne[v]]++;
                    q.push(v);
                }
                else ch[u][i] = ch[ne[u]][i];
            }
        }
    }

    void query(string s)
    {
        // ans = 0;
        for(int k = 0, i = 0; s[k]; k ++)
        {
            i = ch[i][s[k] - 'a'];
            vis[i]++;
        }
        //return ans;
    }
    void topu () 
    { //拓扑排序
        queue<int>q;
        for (int i = 1; i <= cnt1; i++)
        {
            if (!in[i]) q.push (i);
        }
        while (!q.empty()) 
        {
            int u = q.front();
            q.pop ();
            
            ans[cnt[u]] = vis[u];
            
            int v = ne[u];
            vis[v] += vis[u];//更新ne的vis值

            in[v]--;
            if (!in[v])
                q.push (v);
        }
    }
}AC;

void solve()
{
    int n;
    cin >> n;
    AC.clear();
    std::vector<string> arr(n + 10);
    for(int i = 1; i <= n; i ++)
    {
        string s;
        cin >> s;
        AC.ins(s,i);
        arr[i] = s;
    }
    AC.build();
    string s;
    cin >> s;
    AC.query(s);
    AC.topu();
    int ans1 = 0;
    for(int i = 1; i <= n; i ++)
    {
        cout << AC.ans[AC.Map[i]] << endl;
    }
}


int KmpSearch(char* s, char* p)  
{  
    int i = 0;  
    int j = 0;  
    int sLen = strlen(s);  
    int pLen = strlen(p);  
    while (i < sLen && j < pLen)  
    {  
        //①如果j = -1，或者当前字符匹配成功（即S[i] == P[j]），都令i++，j++      
        if (j == -1 || s[i] == p[j])  
        {  
            i++;  
            j++;  
        }  
        else  
        {  
            //②如果j != -1，且当前字符匹配失败（即S[i] != P[j]），则令 i 不变，j = next[j]      
            //next[j]即为j所对应的next值        
            j = next[j];  
        }  
    }  
    if (j == pLen)  
        return i - j;  
    else  
        return -1;  
}